package com.aizhixin.lab.project.template.service;

import com.aizhixin.lab.account.dto.AccountDTO;
import com.aizhixin.lab.common.core.ApiReturnConstants;
import com.aizhixin.lab.common.utils.ExcelUtil;
import com.aizhixin.lab.project.template.domain.ExercisesDomain;
import com.aizhixin.lab.project.template.domain.ExercisesFileDomain;
import com.aizhixin.lab.project.template.domain.ExercisesQuestionChoiceDomain;
import com.aizhixin.lab.project.template.entity.Exercises;
import com.aizhixin.lab.project.template.entity.ExercisesChoice;
import com.aizhixin.lab.project.template.entity.ExercisesFile;
import com.aizhixin.lab.project.template.entity.TaskWorkOrder;
import com.aizhixin.lab.project.template.repository.ExercisesChoiceRepository;
import com.aizhixin.lab.project.template.repository.ExercisesFileRepository;
import com.aizhixin.lab.project.template.repository.ExercisesRepository;
import com.aizhixin.lab.project.template.repository.TaskWorkOrderRepository;
import com.aizhixin.lab.task.core.ExerciseType;
import com.aizhixin.lab.task.core.TaskInforCode;
import com.aizhixin.lab.task.domain.TaskFileDomain;
import com.aizhixin.lab.task.domain.TaskQuestionChoiceDomain;
import com.aizhixin.lab.task.domain.TaskQuestionDomain;
import com.aizhixin.lab.task.entity.Task;
import com.aizhixin.lab.task.entity.TaskFile;
import com.aizhixin.lab.task.entity.TaskQuestionChoice;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.hibernate.NonUniqueResultException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class ExercisesService {
    @Autowired
    private ExercisesRepository exercisesRepository;
    @Autowired
    private ExercisesChoiceRepository choiceRepository;
    @Autowired
    private ExercisesFileRepository fileRepository;
    @Autowired
    private TaskWorkOrderRepository taskWorkOrderRepository;
    public void delete(String id){
        exercisesRepository.deleteByTaskId(id);
    }

    public Map<String, Object> saveQuestionList(List<ExercisesDomain> domainList, AccountDTO dto){
        Map<String, Object> result = new HashMap<String, Object>();
        int i=1;
        for (ExercisesDomain domain:domainList){
            if (domain.getTaskId().isEmpty()) {
                result.put(ApiReturnConstants.SUCCESS, false);
                result.put(ApiReturnConstants.ERROR, "任务id不能为空！");
                return result;
            }
            boolean isFileEmpty = false;
            if (domain.getAccessorylist().isEmpty()) {
                isFileEmpty = true;
            }
            if (StringUtils.isEmpty(domain.getAnswer())){
                result.put(ApiReturnConstants.SUCCESS, false);
                result.put(ApiReturnConstants.ERROR, "第"+i+"题 答案不能为空！");
                return result;
            }
            if (domain.getQuestionContent().isEmpty() && !isFileEmpty) {
                result.put(ApiReturnConstants.SUCCESS, false);
                result.put(ApiReturnConstants.ERROR, "第"+i+"题 题目题干和题干附件不能同时为空！");
                return result;
            }
            if((ExerciseType.MULTIPLE.getIntValue().equals(domain.getQuestionType()) || ExerciseType.SINGLE.getIntValue().equals(domain.getQuestionType()))&&domain.getChoicelist()==null){
                result.put(ApiReturnConstants.SUCCESS, false);
                result.put(ApiReturnConstants.ERROR, "第"+i+"题 客观题选项不能够为空！");
                return result;
            }

            //如果题目类型为编程题选择题则必须传语言类型
            if (domain.getQuestionType() == 60 && domain.getLanguage() == null){
                result.put(ApiReturnConstants.SUCCESS, false);
                result.put(ApiReturnConstants.ERROR, "第"+i+"题 语言种类必须选择！");
                return result;
            }
        }
        if (domainList.size()>0){
            ExercisesDomain exercisesDomain = domainList.get(0);
            exercisesRepository.deleteByTaskId(exercisesDomain.getTaskId());
        }
        for (ExercisesDomain domain:domainList){
            save(domain,dto.getId());
        }
        result.put(ApiReturnConstants.SUCCESS,true);
        result.put(ApiReturnConstants.DATA,"保存成功");
        return result;
    }



    public void save(ExercisesDomain domain,Long createdBy) {
        Exercises exercises = new Exercises();
        Boolean isNew=true;
        if (StringUtils.isEmpty(domain.getId())) {
            domain.setId(UUID.randomUUID().toString());
            isNew=false;
        }
        BeanUtils.copyProperties(domain, exercises);
        exercises.setCreatedBy(createdBy);
        List<ExercisesChoice> choiceList = new ArrayList<ExercisesChoice>();

        if (ExerciseType.MULTIPLE.getIntValue().equals(domain.getQuestionType()) || ExerciseType.SINGLE.getIntValue().equals(domain.getQuestionType()) || ExerciseType.JUDGMENT.getIntValue().equals(domain.getQuestionType())) {
            if (null != domain.getChoicelist() && 0 < domain.getChoicelist().size()) {
//                    List<ExercisesFile> fileList = new ArrayList<ExercisesFile>();
                for (ExercisesQuestionChoiceDomain choiceDomain : domain.getChoicelist()) {
                    ExercisesChoice choice = new ExercisesChoice();
                    if (StringUtils.isEmpty(choiceDomain.getId())) {
                        choiceDomain.setId(UUID.randomUUID().toString());
                    }
//                    String choiceId = UUID.randomUUID().toString();
                    choice.setId(choiceDomain.getId());
                    choice.setOption(choiceDomain.getOption());
                    choice.setChoiceContent(choiceDomain.getChoiceContent());
                    choice.setExercisesQuestionId(domain.getId());
                    choiceList.add(choice);
//                        if (!choiceDomain.getAccessorylist().isEmpty()) {
//                            for (TaskFileDomain accessoryDomain : choiceDomain.getAccessorylist()) {
//                                ExercisesFile accessory = new ExercisesFile();
//                                accessory.setId(UUID.randomUUID().toString());
//                                accessory.setTaskId(domain.getTaskId());
//                                accessory.setTaskQuestionId(questionId);
//                                accessory.setTaskChoiceId(choiceId);
//                                accessory.setSource(TaskInforCode.FILE_FROM_CHOICE);
//                                accessory.setFileName(accessoryDomain.getFileName());
//                                accessory.setFileUrl(accessoryDomain.getFileUrl());
//                                accessory.setFileKey(accessoryDomain.getFileKey());
//                                accessory.setOrderNum(accessoryDomain.getOrderNum());
//                                fileList.add(accessory);
//                            }
//                        }
                }
            }
        }
        List<ExercisesFile> fileDomainList=new ArrayList<>();
        if (domain.getAccessorylist().size() > 0)
            for (ExercisesFileDomain exercisesFileDomain : domain.getAccessorylist()) {
                ExercisesFile exercisesFile = new ExercisesFile();
                exercisesFile.setId(UUID.randomUUID().toString());
                exercisesFile.setTaskId(domain.getTaskId());
                exercisesFile.setExercisesQuestionId(domain.getId());
//            accessory.setTaskChoiceId(choiceId);
//            accessory.setSource(TaskInforCode.FILE_FROM_CHOICE);
                exercisesFile.setFileName(exercisesFileDomain.getFileName());
                exercisesFile.setFileUrl(exercisesFileDomain.getFileUrl());
                exercisesFile.setFileKey(exercisesFileDomain.getFileKey());
                exercisesFile.setOrderNum(exercisesFileDomain.getOrderNum());
//                fileRepository.save(exercisesFile);
                fileDomainList.add(exercisesFile);
            }
        if (isNew){
            fileRepository.deleteByExercisesQuestionId(domain.getId());
            choiceRepository.deleteByExercisesQuestionId(domain.getId());
        }
        fileRepository.save(fileDomainList);
        choiceRepository.save(choiceList);
        exercisesRepository.save(exercises);
    }

    public List<ExercisesDomain> findAllQuestions(String id){
        List<Exercises> exercises = exercisesRepository.findByTaskId(id);
        List<ExercisesDomain> domainList=new ArrayList<>();
        exercises.forEach(item->{
            ExercisesDomain exercisesDomain = new ExercisesDomain();
            BeanUtils.copyProperties(item,exercisesDomain);
            if (ExerciseType.MULTIPLE.getIntValue().equals(item.getQuestionType()) || ExerciseType.SINGLE.getIntValue().equals(item.getQuestionType()) || ExerciseType.JUDGMENT.getIntValue().equals(item.getQuestionType())) {
                List<ExercisesChoice> exercisesChoiceList = choiceRepository.findByExercisesQuestionIdOrderByOption(item.getId());
                List<ExercisesQuestionChoiceDomain> questionChoiceDomainList=new ArrayList<>();
                exercisesChoiceList.forEach(choice->{
                    ExercisesQuestionChoiceDomain domain = new ExercisesQuestionChoiceDomain();
                    BeanUtils.copyProperties(choice,domain);
                    questionChoiceDomainList.add(domain);
                });
                if (ExerciseType.JUDGMENT.getIntValue().equals(item.getQuestionType())) {
                    Collections.reverse(questionChoiceDomainList);
                }
                exercisesDomain.setChoicelist(questionChoiceDomainList);
            }
            List<ExercisesFileDomain> fileDomainList=new ArrayList<>();
            List<ExercisesFile> exercisesFileList = fileRepository.findByExercisesQuestionId(item.getId());
            exercisesFileList.forEach(file->{
                ExercisesFileDomain exercisesFileDomain = new ExercisesFileDomain();
                BeanUtils.copyProperties(file,exercisesFileDomain);
                fileDomainList.add(exercisesFileDomain);
            });
            exercisesDomain.setAccessorylist(fileDomainList);
            domainList.add(exercisesDomain);
        });
        return domainList;
    }

    public String exportExercises(MultipartFile file,Long createBy) throws IOException {
        ExcelUtil excelUtil = new ExcelUtil(file.getInputStream(), "2003");
        Map<String,Integer> map=new HashMap<>();
        Sheet sheet = excelUtil.getWorkbook().getSheetAt(0);
        StringBuffer stringBuffer = new StringBuffer();
        List<Exercises> list=new ArrayList<>();
        List<ExercisesChoice> choiceList = new ArrayList<>();
            int rows = sheet.getLastRowNum();
            for (int r=1;r<=rows;r++){

                Row row = sheet.getRow(r);
                if (StringUtils.isEmpty(excelUtil.getCellValueToString(row.getCell(0)))){
                    continue;
                }
                Exercises domain = new Exercises();
                domain.setId(UUID.randomUUID().toString());
                domain.setQuestionType(Integer.parseInt(excelUtil.getCellValueToString(row.getCell(0))));
                TaskWorkOrder taskWorkOrder=null;
                try {
                     taskWorkOrder = taskWorkOrderRepository.findByWorkOrderNameLikeIgnoreCaseAndDeleteFlag("%" + excelUtil.getCellValueToString(row.getCell(1)).trim() + "%", 0);
                }catch (IncorrectResultSizeDataAccessException e){
                    throw new NullPointerException("第"+r+"行工单名称重复");
                }
                try {
                    domain.setTaskId(taskWorkOrder.getId());
                    domain.setOrderNum(returnOrderNum(map,domain.getTaskId()));
                }catch (NullPointerException e){
                   throw new NullPointerException("第"+r+"行工单名称不存在请修改后重试");
                }

                domain.setQuestionContent(excelUtil.getCellValueToString(row.getCell(2)));
                domain.setAnalysis(excelUtil.getCellValueToString(row.getCell(3)));
                domain.setAnswer(excelUtil.getCellValueToString(row.getCell(4)));
                domain.setCreatedBy(createBy);
                if (domain.getQuestionType()==10||domain.getQuestionType()==20){
                    for (int j=6;j<Integer.parseInt(excelUtil.getCellValueToString(row.getCell(5)))+6;j++){
                        ExercisesChoice exercisesChoice = new ExercisesChoice();
                        exercisesChoice.setId(UUID.randomUUID().toString());
                        exercisesChoice.setExercisesQuestionId(domain.getId());
                        exercisesChoice.setOption(((char)('A'+j-6))+"");
                        exercisesChoice.setChoiceContent(excelUtil.getCellValueToString(row.getCell(j)));
                        choiceList.add(exercisesChoice);
                    }
                }
                if (domain.getQuestionType()==30){
                    choiceList.addAll(returnTF(domain.getId()));
                }
                list.add(domain);
            }

            exercisesRepository.save(list);
            choiceRepository.save(choiceList);

            return stringBuffer.toString();
        }
        private  List<ExercisesChoice>  returnTF(String id){
            List<ExercisesChoice> choiceList = new ArrayList<>();
            ExercisesChoice exercisesChoice = new ExercisesChoice();
            exercisesChoice.setId(UUID.randomUUID().toString());
            exercisesChoice.setExercisesQuestionId(id);
            exercisesChoice.setOption("T");
            exercisesChoice.setChoiceContent("正确");
            choiceList.add(exercisesChoice);
            ExercisesChoice exercisesChoice1 = new ExercisesChoice();
            exercisesChoice1.setId(UUID.randomUUID().toString());
            exercisesChoice1.setExercisesQuestionId(id);
            exercisesChoice1.setOption("F");
            exercisesChoice1.setChoiceContent("错误");
            choiceList.add(exercisesChoice1);
            return choiceList;
        }


        private Integer returnOrderNum(Map<String,Integer> map,String id){
            Integer integer = map.get(id);
            if (Objects.isNull(integer)){
                map.put(id,1);
                return 1;
            }else {
                integer++;
                map.put(id,integer);
                return integer;
            }
        }


}
